﻿using System;
using System.Threading;
using com.itac.easyworks.api.client.mii;
using com.itac.easyworks.api.idl;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using AMStudio.Common;
using System.Globalization;
using Excel = Microsoft.Office.Interop.Excel;
using System.Data;
using AccessDB;
using System.Runtime.InteropServices;

namespace AMStudio.Driver
{
    public class TTACTracDriver : IDisposable
    {
        protected ExceptionManager ExManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();

        public event TracConnectedHandler OnConnected;
        public event TracConnectClosedHandler OnConnectClosed;

        private string fileName;
        public string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }

        private ItacMII ItacMES = null;
        private int sessionId = -1;
        private string errorstring;
        private StationSetupData StationSetup = new StationSetupData();
        private SNInfoData SNInfo = new SNInfoData();
        private TraceRealConfig myConfig = TraceRealConfig.Default;

        public SNInfoData SerialNumberInfo
        {
            get { return SNInfo; }
        }

        private string dispatchMaterialBinNr = string.Empty;
        private string existingBoxNr = string.Empty;
        public string ExistingBoxNr
        {
            get
            {
                return existingBoxNr;
            }
            set
            {
                existingBoxNr = value;
            }
        }
        private string bomCheckWorkOrder = string.Empty;
        private string bomCheckCompName = string.Empty;
        private string materialPartNr = string.Empty;
        private int quantity = 0;
        private int totalQuantity = 0;
        private string activeMaterialBinNr = string.Empty;

        private static DataTable currentMaterialTable = new DataTable();
        private static DataTable activeMaterialTable = new DataTable();
        private static DataTable st1MaterialTable = new DataTable();

        private int housingQuantity = 0;
        private int housingTotalQuantity = 100;
        private string partNr = "";
        private string partDesc = "";
        private string productNO = "";
        static log4net.ILog traceLog = log4net.LogManager.GetLogger("TraceabilityLog");

        public TTACTracDriver()
        {
            ItacMES = new ItacMII();

        }

        public bool Initialize(out int taskid)
        {
            bool ret = false;
            taskid = -1;
            try
            {
                int rt = Open();

                taskid = sessionId;
                if (OnConnected != null)
                {
                    OnConnected(this, rt);
                }
                ret = true;
            }
            catch (Exception ex)
            {
                ExManager.HandleException(ex, "Policy");
            }
            return ret;
        }

        public int Open()
        {
            this.sessionId = -1;
            int ret = ItacMES.apiInit(out this.errorstring);
            if (ret != ItacMIIConstants.RES_OK)
            {
                return ret;
            }

            this.sessionId = ItacMES.apiLogin(myConfig.ValidationSetting, out this.errorstring);
            if (this.sessionId <= ItacMIIConstants.RES_OK)
            {
                return ret;
            }
            ItacLog("---------------------------------------------------------------------------");
            ItacLog("time, productNO, sn, material1, material2, station enable[1-8], failStation");
            return 0;
        }

        public void Dispose()
        {
            Dispose(true);
            //Environment.Exit(0);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (this.sessionId != -1)
                {

                    ItacMES.apiLogout(this.sessionId, out this.errorstring);
                    ItacMES.apiShutdown(out errorstring);
                    ItacMES = null;
                    this.sessionId = -1;
                }
                if (OnConnectClosed != null)
                {
                    OnConnectClosed(this, sessionId);
                }
            }
            catch (Exception ex)
            {
                ExManager.HandleException(ex, "Policy");
            }
        }

        public void Close()
        {
            Dispose();
        }

        ~TTACTracDriver()
        {
            Dispose(false);
        }

        public bool CheckConnection(string stationNr)
        {
            string myWorkOrder;

            string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
            int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
            int result = ItacMES.getStationSetup(sessionId, myConfig.BomCheckSetting.user, out partNr, out i1, out s2, out partDesc, out myWorkOrder, out i2, out s4, out s5, out i3, out s6, out s7, out s8, out errorstring);
            if (result <=-99)
                return false;
            else
                return true;
        }

        public int GetBomItems(string productNO, out DataTable dt)
        {
            dt = null;
            try
            {
                int result = -1;
                errorstring = "StationSetup error!";
                string stationNr = myConfig.BomCheckSetting.user;
                string myWorkOrder;
                string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
                int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
                result = ItacMES.getStationSetup(sessionId, stationNr, out partNr, out i1, out s2, out partDesc, out myWorkOrder, out i2, out s4, out s5, out i3, out s6, out s7, out s8, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                this.productNO = productNO;
                if (productNO != partNr)
                {
                    return -1001;
                }
                bomCheckWorkOrder = myWorkOrder;
                int numberOfRecords;
                com.itac.easyworks.api.idl.BomItemData[] bomItemData = new com.itac.easyworks.api.idl.BomItemData[10];
                result = ItacMES.getBomItems(sessionId, stationNr, myWorkOrder, "-1", 0, 1, 0, out numberOfRecords, out bomItemData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                currentMaterialTable.Rows.Clear();
                currentMaterialTable.Columns.Clear();
                currentMaterialTable.Columns.Add(new DataColumn("compName", typeof(string)));
                currentMaterialTable.Columns.Add(new DataColumn("partNo", typeof(string)));
                currentMaterialTable.Columns.Add(new DataColumn("sn", typeof(string)));
                currentMaterialTable.Columns.Add(new DataColumn("quantity", typeof(int)));
                currentMaterialTable.Columns.Add(new DataColumn("useAmount", typeof(int)));

                activeMaterialTable.Rows.Clear();
                activeMaterialTable.Columns.Clear();
                activeMaterialTable.Columns.Add(new DataColumn("compName", typeof(string)));
                activeMaterialTable.Columns.Add(new DataColumn("partNo", typeof(string)));
                activeMaterialTable.Columns.Add(new DataColumn("sn", typeof(string)));
                activeMaterialTable.Columns.Add(new DataColumn("quantity", typeof(int)));
                activeMaterialTable.Columns.Add(new DataColumn("useAmount", typeof(int)));

                st1MaterialTable.Rows.Clear();
                st1MaterialTable.Columns.Clear();
                st1MaterialTable.Columns.Add(new DataColumn("compName", typeof(string)));
                st1MaterialTable.Columns.Add(new DataColumn("alias", typeof(string)));
                st1MaterialTable.Columns.Add(new DataColumn("partNo", typeof(string)));
                st1MaterialTable.Columns.Add(new DataColumn("sn", typeof(string)));
                st1MaterialTable.Columns.Add(new DataColumn("quantity", typeof(int)));
                st1MaterialTable.Columns.Add(new DataColumn("useAmount", typeof(int)));
                st1MaterialTable.Columns.Add(new DataColumn("activeSn", typeof(string)));
                st1MaterialTable.Columns.Add(new DataColumn("activeQuantity", typeof(int)));

                foreach (var item in bomItemData)
                {
                    if (item.setup == 1)
                    {
                        string compName_Translation = string.Empty;
                        //if (AWinFormShell.LanguageString == "中文" 
                        //    && TranslationDB.TranslationTags.ContainsKey(item.compName) 
                        //    && TranslationDB.TranslationTags[item.compName].TranslationType == "英汉")
                        if (TranslationDB.TranslationTags.ContainsKey(item.compName)
                            && TranslationDB.TranslationTags[item.compName].TranslationType == "英汉")
                        {
                            compName_Translation = TranslationDB.TranslationTags[item.compName].Destination;
                        }
                        else
                        {
                            compName_Translation = item.compName;

                            TranslationItem translationItem = new TranslationItem();
                            translationItem.TranslationType = "英汉";
                            translationItem.Source = item.compName;
                            translationItem.Destination = item.compName;
                            TranslationDB.Add(translationItem);

                        }

                        DataRow dr = activeMaterialTable.NewRow();
                        dr["compName"] = item.compName;
                        dr["partNo"] = item.partNo;
                        dr["quantity"] = 0;
                        dr["useAmount"] = item.quantity;

                        activeMaterialTable.Rows.Add(dr);

                        dr = currentMaterialTable.NewRow();
                        dr["compName"] = item.compName;
                        dr["partNo"] = item.partNo;
                        dr["quantity"] = 0;
                        dr["useAmount"] = item.quantity;
                        currentMaterialTable.Rows.Add(dr);

                        dr = st1MaterialTable.NewRow();
                        dr["compName"] = item.compName;
                        dr["alias"] = compName_Translation;
                        dr["partNo"] = item.partNo;
                        dr["quantity"] = 0;
                        dr["useAmount"] = item.quantity;
                        dr["activeQuantity"] = 0;
                        st1MaterialTable.Rows.Add(dr);
                    }
                }
                dt = st1MaterialTable.Copy();

                result = ItacMES.setupActivation(sessionId, stationNr, 2, myWorkOrder, 2, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int ActivateMaterial(string scannedMaterialNr, out DataTable dt)
        {
            dt = currentMaterialTable.Copy();
            try
            {
                int result = -1;
                string stationNr = myConfig.BomCheckSetting.user;
                errorstring = "ActivateMaterialBox error!";
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, stationNr, scannedMaterialNr, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                result = -1;
                for (int i = 0; i < currentMaterialTable.Rows.Count; i++)
                {
                    if (currentMaterialTable.Rows[i]["partNo"].ToString() == materialBinData.productNr
                         && (int)materialBinData.quantity > 0)
                    {
                        currentMaterialTable.Rows[i]["sn"] = scannedMaterialNr;
                        currentMaterialTable.Rows[i]["quantity"] = 0;
                        result = 0;
                    }
                }
                dt = currentMaterialTable.Copy();
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int ActivateMaterial2(string scannedMaterialNr, out DataTable dt, out string errorstring)
        {
            errorstring = "ActivateMaterialBox error!";
            dt = activeMaterialTable.Copy();
            try
            {
                int result = -1;
                string stationNr = myConfig.BomCheckSetting.user;
                string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
                //int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, stationNr, scannedMaterialNr, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                //if (materialBinData.quantity <= 0)
                //{
                //    errorstring = "物料数量为0";
                //    return -2;
                //}
                string partNo = materialBinData.productNr;
                bool isWorkorderOK = false;
                for (int j = 0; j < activeMaterialTable.Rows.Count; j++)
                {
                    if (activeMaterialTable.Rows[j]["partNo"].ToString() == partNo)
                    {
                        isWorkorderOK = true;
                    }
                }
                if (isWorkorderOK == false)
                    return -1;

                //bool isAllMaterialOK = true;
                for (int i = 0; i < activeMaterialTable.Rows.Count; i++)
                {
                    if (activeMaterialTable.Rows[i]["partNo"].ToString() == materialBinData.productNr)
                    {
                        result = ItacMES.setupActivation(sessionId, stationNr, 2, bomCheckWorkOrder, 1, out errorstring);
                        if (result != ItacMIIConstants.RES_OK)
                            return result;
                        com.itac.easyworks.api.idl.SetupPrepareData[] setupPrepareDataArray = new com.itac.easyworks.api.idl.SetupPrepareData[1];
                        setupPrepareDataArray[0].materialBinNr = scannedMaterialNr;
                        setupPrepareDataArray[0].position = activeMaterialTable.Rows[i]["compName"].ToString();
                        result = ItacMES.updateSetupData(sessionId, stationNr, 2, 0, 1, setupPrepareDataArray, out errorstring);
                        if (result != ItacMIIConstants.RES_OK)
                            return result;
                        result = ItacMES.setupActivation(sessionId, stationNr, 2, bomCheckWorkOrder, 0, out errorstring);
                        if (result != ItacMIIConstants.RES_OK)
                            return result;

                        activeMaterialTable.Rows[i]["sn"] = scannedMaterialNr;
                        activeMaterialTable.Rows[i]["quantity"] = materialBinData.quantity;
                        dt = activeMaterialTable.Copy();
                        foreach (DataRow dr in st1MaterialTable.Rows)
                        {
                            if (dr["partNo"].ToString() == activeMaterialTable.Rows[i]["partNo"].ToString())
                            {
                                dr["activeSn"] = activeMaterialTable.Rows[i]["sn"].ToString();
                                dr["activeQuantity"] = activeMaterialTable.Rows[i]["quantity"].ToString();
                            }
                        }
                    }
                    //if ((int)currentMaterialTable.Rows[i]["quantity"] <= 0)
                    //{
                    //    isAllMaterialOK = false;
                    //}
                }

                //if (isAllMaterialOK)
                {
                    int numberOfRecords;
                    com.itac.easyworks.api.idl.BomCompFailData[] bomCompFailDataArray = new com.itac.easyworks.api.idl.BomCompFailData[1];
                    result = ItacMES.bomCheckForWorkorder(sessionId, stationNr, 2, bomCheckWorkOrder, 1, out numberOfRecords, out bomCompFailDataArray, out errorstring);
                    //if (result != ItacMIIConstants.RES_OK)
                    //return result;
                }
                return 0;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int CheckMaterial(string scannedMaterialNr, out DataTable dt, out string errorstring)
        {
            dt = st1MaterialTable.Copy();
            errorstring = "";
            try
            {
                int result = -1;
                string stationNr = myConfig.BomCheckSetting.user;
                errorstring = "ActivateMaterialBox error!";
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, stationNr, scannedMaterialNr, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                result = -1;
                if (materialBinData.quantity <= 0)
                {
                    errorstring = "物料数量为0";
                    return -2;
                }
                //currentMaterialTable = activeMaterialTable.Copy();
                for (int i = 0; i < st1MaterialTable.Rows.Count; i++)
                {
                    if (st1MaterialTable.Rows[i]["partNo"].ToString() == materialBinData.productNr
                         && (int)materialBinData.quantity > 0)
                    {
                        st1MaterialTable.Rows[i]["sn"] = scannedMaterialNr;
                        st1MaterialTable.Rows[i]["quantity"] = (int)materialBinData.quantity;
                        result = 0;
                    }
                }
                dt = st1MaterialTable.Copy();
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int UploadState2(string sn, int state, out int quantity, out int totalQuantity)
        {
            quantity = housingQuantity;
            totalQuantity = housingTotalQuantity;
            try
            {
                int result = -1;
                string stationNr = myConfig.BomCheckSetting.user;
                com.itac.easyworks.api.idl.SerialNumberData[] serialNumberData = new com.itac.easyworks.api.idl.SerialNumberData[1];
                serialNumberData[0].serialNumber = sn;
                serialNumberData[0].serialNumberPos = "-1";
                result = ItacMES.assignSerialNumberToWorkOrder(this.sessionId, stationNr, 2, sn, "-1", 1, serialNumberData, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                if (state == 0)
                {
                    result = ItacMES.uploadState(this.sessionId, stationNr, 2, sn, "-1", 0, 0, 0, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) return result;
                }
                else
                {
                    result = ItacMES.uploadState(this.sessionId, stationNr, 2, sn, "-1", 1, 0, 0, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) return result;
                }
                housingQuantity += 1;
                quantity += 1;
                if (housingQuantity == housingTotalQuantity)
                {
                    //todo print
                }
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int UploadState8(string sn, int state, out string errorstring)
        {
            errorstring = "";
            try
            {
                int result = -1;
                string stationNr = myConfig.BomCheckSetting.user;
                int loopCounter;
                result = ItacMES.checkSerialNumberState(this.sessionId, stationNr, 2, sn, "-1", out loopCounter, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                int records;
                com.itac.easyworks.api.idl.BomCompFailData[] bomCompFailData = new com.itac.easyworks.api.idl.BomCompFailData[1];
                result = ItacMES.bomCheck(sessionId, stationNr, 2, sn, 1, out records, out bomCompFailData, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                if (state == 0)
                {
                    result = ItacMES.uploadState(this.sessionId, stationNr, 2, sn, "-1", 0, 0, 0, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) 
                        return result;
                    return result;
                }
                else if (state == 3 || state == 5 || state == 6)
                {
                    com.itac.easyworks.api.idl.CompFailData[] compFailDataArray = new com.itac.easyworks.api.idl.CompFailData[1];
                    compFailDataArray[0].compName = "pressfit";
                    compFailDataArray[0].compPartNo = "";
                    compFailDataArray[0].failureCause = "";

                    compFailDataArray[0].infoText = "";
                    compFailDataArray[0].processLayer = 2;
                    compFailDataArray[0].repair = 0;
                    switch (state)
                    {
                        case 3: compFailDataArray[0].failureType = "1703"; break;
                        case 5: compFailDataArray[0].failureType = "1702"; break;
                        case 6: compFailDataArray[0].failureType = "1705"; break;
                    }
                    result = ItacMES.uploadStateAndFailureData(sessionId, stationNr, 2, "-1", "-1", sn, "-1", "1", 1, 0, compFailDataArray, 0, -1, out loopCounter, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) return result;
                    return result;
                }
                else
                {
                    result = ItacMES.uploadState(this.sessionId, stationNr, 2, sn, "-1", 1, 0, 0, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) return result;
                    return result;
                }
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int InsertHousingMaterial(string sn, out DataTable dt)
        {
            dt = currentMaterialTable.Copy();
            try
            {
                //check housing's partNo
                //bool isRightHousing = false;
                //foreach (DataRow row in currentMaterialTable.Rows)
                //{
                //    if (sn.Contains(row["partNo"].ToString()))
                //    {
                //        isRightHousing = true;
                //    }
                //}
                //if (!isRightHousing)
                //{
                //    return -1;
                //}
                string sql = string.Format("SELECT * FROM HOUSING WHERE MATERIAL = '{0}'", currentMaterialTable.Rows[0]["sn"].ToString());
                DataTable materialTable = AccessHelper.dataTable(sql);
                int count = materialTable.Rows.Count + 1;
                for (int i = 0; i < currentMaterialTable.Rows.Count; i++)
                {
                    sql = string.Format("INSERT INTO HOUSING VALUES('{0}','{1}')", sn, currentMaterialTable.Rows[i]["sn"].ToString());
                    AccessHelper.excuteSql(sql);
                    string stationNr = myConfig.BomCheckSetting.user;
                    com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                    int result = ItacMES.getMaterialBinInfo(sessionId, stationNr, currentMaterialTable.Rows[i]["sn"].ToString(), out materialBinData, out errorstring);
                    if (result != ItacMIIConstants.RES_OK)
                        return result;
                    currentMaterialTable.Rows[i]["quantity"] = (int)materialBinData.quantity - count * int.Parse(currentMaterialTable.Rows[i]["useAmount"].ToString());
                }
                dt = currentMaterialTable.Copy();
            }
            catch (System.Exception ex)
            {
                return -1;
            }
            return 0;
        }

        public int PrintTempNr(int quantity, string printFileName)
        {
            PrintHousingTemplate(quantity, printFileName);
            string sql = string.Format("UPDATE HOUSING_QUANTITY SET QUANTITY = {0}", 0);
            AccessHelper.excuteSql(sql);
            return 0;
        }

        public int Reprint(int quantity, string printFileName)
        {
            PrintHousingTemplate(quantity, printFileName);
            return 0;
        }

        public int Assembly(int quantity)
        {
            string sql = string.Format("UPDATE HOUSING_QUANTITY SET QUANTITY = {0}", quantity);
            AccessHelper.excuteSql(sql);
            return 0;
        }

        public int PrintHousingTemplate(int quantity, string printFileName)
        {

            Excel.Application xlsApp = null;
            Excel.Workbook workbook = null;
            xlsApp = new Excel.Application();
            xlsApp.Visible = false;
            workbook = xlsApp.Workbooks.Open(printFileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            if (workbook == null)
            {
                return -1;
            }
            Excel.Worksheet worksheet = workbook.Sheets[1] as Excel.Worksheet;
            Excel.Range range = worksheet.get_Range("B1", Type.Missing);
            range.Value2 = partNr;
            range = worksheet.get_Range("D4", Type.Missing);
            range.Value2 = partDesc;
            range = worksheet.get_Range("B3", Type.Missing);
            range.Value2 = quantity;
            foreach (DataRow row in activeMaterialTable.Rows)
            {
                if (row["compName"].ToString() == "HOUSING")
                {
                    range = worksheet.get_Range("B5", Type.Missing);
                    range.Value2 = row["partNo"].ToString();
                }
                else if (row["compName"].ToString() == "CAPACITOR")
                {
                    range = worksheet.get_Range("B7", Type.Missing);
                    range.Value2 = row["partNo"].ToString();
                }
                else if (row["compName"].ToString() == "IDC")
                {
                    range = worksheet.get_Range("B9", Type.Missing);
                    range.Value2 = row["partNo"].ToString();
                }
            }
            string date = "P" + DateTime.Now.ToString("yyyyMMdd");
            range = worksheet.get_Range("E9", Type.Missing);
            range.Value2 = date;
            worksheet.PrintOutEx(Type.Missing, Type.Missing, Type.Missing, false, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            workbook.Close(false);
            xlsApp.Quit();

            return 0;
        }

        public int UploadState(string sn, int state, int totalQuantity, string printFileName, bool dispatchFlag, string[] materialArray, bool[] enableArray, out int quantity, out DataTable dt, out string errorstring)
        {
            quantity = 0;
            dt = activeMaterialTable;
            int result = -1;
            string stationNr = myConfig.BomCheckSetting.user;

            // active material
            foreach (string materialSN in materialArray)
            {
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, stationNr, materialSN, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                string partNo = materialBinData.productNr;
                for (int j = 0; j < activeMaterialTable.Rows.Count; j++)
                {
                    if (activeMaterialTable.Rows[j]["partNo"].ToString() == partNo)
                    {
                        if (activeMaterialTable.Rows[j]["sn"].ToString() != materialSN)
                        {
                            result = ActivateMaterial2(materialSN, out dt, out errorstring);
                            if (result < 0)
                                return -1001;
                        }
                    }
                }
            }
            dt = activeMaterialTable;
            if (UploadState8(sn, state, out errorstring) != 0)
                return -1;
            //update quantity
            foreach (string materialSN in materialArray)
            {
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, stationNr, materialSN, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                string partNo = materialBinData.productNr;
                for (int j = 0; j < activeMaterialTable.Rows.Count; j++)
                {
                    if (activeMaterialTable.Rows[j]["partNo"].ToString() == partNo)
                    {
                        activeMaterialTable.Rows[j]["quantity"] = materialBinData.quantity;
                    }
                }
            }
            string str = DateTime.Now.ToString() + " , " + productNO + ", "
                + sn + ", ";
            for (int j = 0; j < activeMaterialTable.Rows.Count; j++)
                str += activeMaterialTable.Rows[j]["sn"].ToString() + ", ";
            for (int i = 1; i < 9; i++)
            {
                if (enableArray[i-1])
                    str += i.ToString() + " Enable" + ", ";
                else
                    str += i.ToString() + " Disable" + ", ";
            }
            str += "failStation: " + state.ToString() + " , ";
            ItacLog(str);
            return 0;
        }





        public int BomCheckStationSetup(out string workOrder, out string compName, out string partNr)
        {
            compName = "";
            workOrder = "";
            partNr = "";
            try
            {
                int result = -1;
                errorstring = "StationSetup error!";
                string stationNr = myConfig.BomCheckSetting.user;
                string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
                int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
                result = ItacMES.getStationSetup(sessionId, stationNr, out partNr, out i1, out s2, out s3, out workOrder, out i2, out s4, out s5, out i3, out s6, out s7, out s8, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                bomCheckWorkOrder = workOrder;
                int numberOfRecords;
                com.itac.easyworks.api.idl.BomItemData[] bomItemData = new com.itac.easyworks.api.idl.BomItemData[10];
                result = ItacMES.getBomItems(sessionId, stationNr, workOrder, "-1", 0, 1, 0, out numberOfRecords, out bomItemData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                compName = bomItemData[0].compName;
                materialPartNr = bomItemData[0].partNo;
                bomCheckCompName = compName;
                result = ItacMES.setupActivation(sessionId, stationNr, 2, workOrder, 2, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public bool CheckMaterial(string scannedMaterialNr)
        {
            int result = -1;
            string stationNr = myConfig.BomCheckSetting.user;
            com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
            result = ItacMES.getMaterialBinInfo(sessionId, stationNr, scannedMaterialNr, out materialBinData, out errorstring);
            if (result != ItacMIIConstants.RES_OK)
                return false;
            return true;
            //if (materialBinData.productNr == materialPartNr)
            //{
            //    return true;
            //}
            //else
            //{
            //    return false;
            //}
        }

        public int ActivateMaterialBox(string scannedMaterialNr)
        {
            try
            {
                int result = -1;
                string stationNr = myConfig.BomCheckSetting.user;
                errorstring = "ActivateMaterialBox error!";
                string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
                int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, stationNr, scannedMaterialNr, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                result = ItacMES.setupActivation(sessionId, stationNr, 2, bomCheckWorkOrder, 1, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                com.itac.easyworks.api.idl.SetupPrepareData[] setupPrepareDataArray = new com.itac.easyworks.api.idl.SetupPrepareData[1];
                setupPrepareDataArray[0].materialBinNr = scannedMaterialNr;
                setupPrepareDataArray[0].position = bomCheckCompName;
                result = ItacMES.updateSetupData(sessionId, stationNr, 2, 0, 1, setupPrepareDataArray, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                result = ItacMES.setupActivation(sessionId, stationNr, 2, bomCheckWorkOrder, 0, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                int numberOfRecords;
                com.itac.easyworks.api.idl.BomCompFailData[] bomCompFailDataArray = new com.itac.easyworks.api.idl.BomCompFailData[1];
                result = ItacMES.bomCheckForWorkorder(sessionId, stationNr, 2, bomCheckWorkOrder, 1, out numberOfRecords, out bomCompFailDataArray, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int DoBomCheck(string serialNumber, string housingId, string scannedMaterialNr, string partNr, out double quantity, out double totalQuantity)
        {
            quantity = -1;
            totalQuantity = -1;
            try
            {

                #region TRY
                int result = -1;
                string stationNr = myConfig.BomCheckSetting.user;
                string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
                int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
                string snPartNr = string.Empty;

                result = ItacMES.getSerialnumberInfo(sessionId, serialNumber, "-1", out snPartNr, out i1, out s1, out s2, out s3, out i2, out s4, out s5, out s6, out s7, out s8, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                {
                    if (result == -2)
                        return -1014;   //sn not found
                    return result;
                }
                if (snPartNr != partNr)
                {
                    errorstring = "snPartNr != partNr";
                    return -1015;   //partNr not correct
                    //????????????????????????????
                }
                result = ItacMES.checkSerialNumberState(sessionId, stationNr, 2, serialNumber, "-1", out i1, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return -1;
                com.itac.easyworks.api.idl.BomCompFailData[] bcfdArray = new com.itac.easyworks.api.idl.BomCompFailData[10];
                result = ItacMES.bomCheck(sessionId, stationNr, 2, serialNumber, 1, out i1, out bcfdArray, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                if (housingId.Length > 0)
                {
                    result = ItacMES.appendAttributeToSerialNumber(sessionId, stationNr, serialNumber, "RSU_HOUSING_ID", housingId, out errorstring);
                    if (result != ItacMIIConstants.RES_OK && result != -96)
                        return -1016;   //append housing id error
                    if (result == -96)
                    {

                        result = ItacMES.removeAttributeFromSerialNumber(sessionId, stationNr, serialNumber, "RSU_HOUSING_ID", out errorstring);
                        if (result != ItacMIIConstants.RES_OK && result != -72)
                            return -1016;
                        if (result == 0 || result == -72)
                        {
                            result = ItacMES.appendAttributeToSerialNumber(sessionId, stationNr, serialNumber, "RSU_HOUSING_ID", housingId, out errorstring);
                            if (result != ItacMIIConstants.RES_OK)
                                return -1016;
                        }
                    }
                }
                result = ItacMES.uploadState(sessionId, stationNr, 2, serialNumber, "-1", 0, 0, 1, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, stationNr, scannedMaterialNr, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                quantity = materialBinData.quantity;
                totalQuantity = materialBinData.totalQuantity;
                return 0;
                #endregion
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public object DoBomCheck2(string serialNumber, string housingId, string scannedMaterialNr, string partNr)
        {
            int result = -1;
            int quantity = -1;
            int totalQuantity = -1;
            int[] intRes = new int[] { result, quantity, totalQuantity };
            try
            {
                #region TRY
                string stationNr = myConfig.BomCheckSetting.user;
                string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
                int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
                string snPartNr = string.Empty;
                if (scannedMaterialNr != activeMaterialBinNr)
                {
                    if (ActivateMaterialBox(scannedMaterialNr) >= 0)
                    {
                        activeMaterialBinNr = scannedMaterialNr;
                    }
                    else
                    {
                        intRes[0] = -1017;
                        return intRes;
                    }

                }
                intRes[0] = ItacMES.getSerialnumberInfo(sessionId, serialNumber, "-1", out snPartNr, out i1, out s1, out s2, out s3, out i2, out s4, out s5, out s6, out s7, out s8, out errorstring);
                if (intRes[0] != ItacMIIConstants.RES_OK)
                {
                    if (intRes[0] == -2)
                    {
                        intRes[0] = -1014;   //sn not found
                        return intRes;
                    }
                    return intRes;
                }
                if (snPartNr != partNr)
                {
                    errorstring = "snPartNr != partNr";
                    intRes[0] = -1015;   //partNr not correct
                    return intRes;
                    //????????????????????????????
                }
                intRes[0] = ItacMES.checkSerialNumberState(sessionId, stationNr, 2, serialNumber, "-1", out i1, out errorstring);
                if (intRes[0] != ItacMIIConstants.RES_OK)
                    return intRes;
                com.itac.easyworks.api.idl.BomCompFailData[] bcfdArray = new com.itac.easyworks.api.idl.BomCompFailData[10];
                intRes[0] = ItacMES.bomCheck(sessionId, stationNr, 2, serialNumber, 1, out i1, out bcfdArray, out errorstring);
                if (intRes[0] != ItacMIIConstants.RES_OK)
                    return intRes;
                if (housingId.Length > 0)
                {
                    intRes[0] = ItacMES.appendAttributeToSerialNumber(sessionId, stationNr, serialNumber, "RSU_HOUSING_ID", housingId, out errorstring);
                    if (intRes[0] != ItacMIIConstants.RES_OK && intRes[0] != -96)
                    {
                        intRes[0] = -1016;   //append housing id error
                        return intRes;
                    }
                    if (intRes[0] == -96)
                    {

                        intRes[0] = ItacMES.removeAttributeFromSerialNumber(sessionId, stationNr, serialNumber, "RSU_HOUSING_ID", out errorstring);
                        if (intRes[0] != ItacMIIConstants.RES_OK && result != -72)
                        {
                            intRes[0] = -1016;
                            return intRes;
                        }
                        if (intRes[0] == 0 || intRes[0] == -72)
                        {
                            intRes[0] = ItacMES.appendAttributeToSerialNumber(sessionId, stationNr, serialNumber, "RSU_HOUSING_ID", housingId, out errorstring);
                            if (intRes[0] != ItacMIIConstants.RES_OK)
                            {
                                intRes[0] = -1016;
                                return intRes;
                            }
                        }
                    }
                }
                intRes[0] = ItacMES.uploadState(sessionId, stationNr, 2, serialNumber, "-1", 0, 0, 1, out errorstring);
                if (intRes[0] != ItacMIIConstants.RES_OK)
                    return intRes;
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                intRes[0] = ItacMES.getMaterialBinInfo(sessionId, stationNr, scannedMaterialNr, out materialBinData, out errorstring);
                if (intRes[0] != ItacMIIConstants.RES_OK)
                    return intRes;
                intRes[0] = 0;
                intRes[1] = (int)materialBinData.quantity;
                intRes[2] = (int)materialBinData.totalQuantity;
                return intRes;
                #endregion
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public object UploadAndDispatch(string serialNumber, string customerSN, int failStation, bool isDispatch)
        {
            object[] objRes = new object[] { 0, "", 0, 0 };
            string outDispatchNr;
            int outQuantity;
            if (SetProductState(serialNumber, customerSN, failStation) < 0)
            {
                objRes[0] = -1004;  //upload error
            }
            if (Convert.ToInt32(objRes[0]) == 0 && failStation == 0 && isDispatch)
            {
                if (AddSnToBox(customerSN, out outDispatchNr, out outQuantity) < 0)
                {
                    objRes[0] = -1005;  //dispatch error
                }
                objRes[1] = dispatchMaterialBinNr;
                objRes[2] = outQuantity;
                objRes[3] = this.totalQuantity;
            }
            return (object)objRes;
        }

        public int CreateNewBox(out string materialBinNr, out double quantity, out double totalQuantity)
        {
            int result = -1;
            quantity = -1;
            totalQuantity = -1;
            materialBinNr = string.Empty;
            errorstring = "CreateNewBox error!";
            try
            {
                string workOrder = string.Empty;
                string dispatchStationNr = myConfig.DipatchValidationSetting.user;
                string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
                int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
                result = ItacMES.getStationSetup(sessionId, dispatchStationNr, out s1, out i1, out s2, out s3, out workOrder, out i2, out s4, out s5, out i3, out s6, out s7, out s8, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                result = ItacMES.getNextMaterialBinNumber(sessionId, dispatchStationNr, "DC_ACU", out materialBinNr, out errorstring);
                if (result != ItacMIIConstants.RES_OK)
                    return result;
                materialBinNr = materialBinNr.Substring(6, (materialBinNr.Length - 6));
                dispatchMaterialBinNr = materialBinNr;
                string changeNr = workOrder;
                string time = DateTime.Now.ToString("yyyyMMdd");
                result = ItacMES.createNewMaterialBin(sessionId, dispatchStationNr, materialBinNr, "DC_ACU", changeNr, time, 1, out errorstring);
                if (result < 0) return result;
                result = ItacMES.shipActivateShippingLotAtKap(sessionId, dispatchStationNr, materialBinNr, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                com.itac.easyworks.api.idl.MaterialBinData materialBinData = new com.itac.easyworks.api.idl.MaterialBinData();
                result = ItacMES.getMaterialBinInfo(sessionId, dispatchStationNr, materialBinNr, out materialBinData, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                quantity = materialBinData.quantity;
                totalQuantity = materialBinData.totalQuantity;
                try
                {
                    int id = 1;
                    DataTable dt = AccessHelper.dataTable("select top 1 * from DISPATCH ORDER BY ID DESC");
                    if (dt.Rows.Count > 0)
                    {
                        DataRow dr = dt.Rows[0];
                        id = Convert.ToInt32(dr[0]) + 1;
                        if (dr[1].ToString() != dispatchMaterialBinNr)
                        {
                            string date = DateTime.Now.ToString("yyyyMMdd");
                            string sql = "insert into DISPATCH values(" + id + ",'" + dispatchMaterialBinNr + "', '0', '" + date + "')";
                            AccessHelper.excuteSql(sql);
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    return -1006;
                }
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        public int ActivateExistingBox(string scannedBoxNr, out string materialBinNr, out double quantity, out double totalQuantity)
        {
            int result = -1;
            quantity = -1;
            totalQuantity = -1;
            materialBinNr = string.Empty;
            errorstring = string.Empty;
            try
            {
                string dispatchStationNr = myConfig.DipatchValidationSetting.user;
                ShippingLotStruct shippingLotStruct = new ShippingLotStruct();
                result = ItacMES.shipGetShippingLotForLotNo(sessionId, dispatchStationNr, scannedBoxNr, out shippingLotStruct, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                //if (shippingLotStruct.beaStatus == "C") return -1;
                if (dispatchMaterialBinNr == string.Empty)
                {
                    result = ItacMES.shipActivateShippingLotAtKap(sessionId, dispatchStationNr, scannedBoxNr, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) return result;
                    ItacMES.shipReopenShippingLot(sessionId, dispatchStationNr, scannedBoxNr, out errorstring);
                    //if (result != ItacMIIConstants.RES_OK) return result;
                }
                existingBoxNr = "";
                materialBinNr = scannedBoxNr;
                dispatchMaterialBinNr = scannedBoxNr;
                quantity = shippingLotStruct.meRest;
                this.quantity = (int)shippingLotStruct.meRest;
                totalQuantity = shippingLotStruct.meTotal;
                try
                {
                    int id = 1;
                    DataTable dt = AccessHelper.dataTable("select top 1 * from DISPATCH ORDER BY ID DESC");
                    if (dt.Rows.Count > 0)
                    {
                        DataRow dr = dt.Rows[0];
                        id = Convert.ToInt32(dr[0]) + 1;
                        if (dr[1].ToString() != dispatchMaterialBinNr)
                        {
                            string date = DateTime.Now.ToString("yyyyMMdd");
                            string sql = "insert into DISPATCH values(" + id + ",'" + dispatchMaterialBinNr + "', '0', '" + date + "')";
                            AccessHelper.excuteSql(sql);
                        }
                    }

                }
                catch (System.Exception ex)
                {
                    return -1006;
                }
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        //return:
        //1：箱子未满
        //2:箱子满了
        public int AddSnToBox(string scannedCustomerSNR, out string outDispatchMaterialBinNr, out int myquantity)
        {
            int result = -1;
            errorstring = "AddSnToBox error!";
            outDispatchMaterialBinNr = string.Empty;
            myquantity = 0;
            string s1 = string.Empty, s2 = string.Empty, s3 = string.Empty, s4 = string.Empty, s5 = string.Empty, s6 = string.Empty, s7 = string.Empty, s8 = string.Empty, s9 = string.Empty;
            int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
            try
            {
                //生成新的箱号
                if (dispatchMaterialBinNr == string.Empty)
                {
                    double quantity;
                    double totalQuantity;
                    if (existingBoxNr == string.Empty)
                    {
                        CreateNewBox(out dispatchMaterialBinNr, out quantity, out totalQuantity);
                        outDispatchMaterialBinNr = dispatchMaterialBinNr;
                    }
                    else
                    {
                        ActivateExistingBox(existingBoxNr, out dispatchMaterialBinNr, out quantity, out totalQuantity);
                        existingBoxNr = string.Empty;
                        this.quantity = (int)quantity;
                    }

                }
                string dispatchStationNr = myConfig.DipatchValidationSetting.user;
                #region Read customer serial number
                result = ItacMES.getStationSetup(sessionId, dispatchStationNr, out s1, out i1, out s2, out s3, out s4, out i2, out s5, out s6, out i3, out s7, out s8, out s9, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                com.itac.easyworks.api.idl.SerialNumberStruct[] serialNrArray = new com.itac.easyworks.api.idl.SerialNumberStruct[1];
                result = ItacMES.getSerialNumbersForAttribute(sessionId, dispatchStationNr, "CUST_SERIAL_NO", scannedCustomerSNR, out serialNrArray, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                string serialNumberSlave = serialNrArray[0].serialNumber;
                #endregion

                #region Product level change
                result = ItacMES.verifyMerge(sessionId, dispatchStationNr, serialNumberSlave, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                com.itac.easyworks.api.idl.SerialNumberData[] serialNumberData = new com.itac.easyworks.api.idl.SerialNumberData[1];
                serialNumberData[0].serialNumber = serialNrArray[0].serialNumber;
                serialNumberData[0].serialNumberPos = "-1";

                result = ItacMES.assignSerialNumberToWorkOrder(this.sessionId, dispatchStationNr, 2, serialNumberSlave, "-1", 1, serialNumberData, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                result = ItacMES.mergeParts(this.sessionId, dispatchStationNr, 2, 0, serialNumberSlave, serialNumberSlave, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                result = ItacMES.uploadState(this.sessionId, dispatchStationNr, 2, serialNumberSlave, "-1", 0, 0, 0, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                result = ItacMES.switchSerialNumber(sessionId, dispatchStationNr, 2, 0, serialNumberSlave, scannedCustomerSNR, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                #endregion

                ItacMES.shipActivateShippingLotAtKap(sessionId, dispatchStationNr, dispatchMaterialBinNr, out errorstring);

                result = ItacMES.shipAddSnrToShippingLot(sessionId, dispatchStationNr, dispatchMaterialBinNr, scannedCustomerSNR, out errorstring);
                if (result < 0) return result;
                ShippingLotStruct shippingLot;
                int res1 = ItacMES.shipGetShippingLotForLotNo(sessionId, myConfig.DipatchValidationSetting.user, dispatchMaterialBinNr, out shippingLot, out errorstring);
                if (res1 == ItacMIIConstants.RES_OK)
                {
                    this.quantity = (int)shippingLot.meRest;
                    myquantity = (int)shippingLot.meRest;
                    this.totalQuantity = (int)shippingLot.meTotal;
                    //outDispatchMaterialBinNr = dispatchMaterialBinNr;
                }
                if (result == 2)
                {
                    Dispatch(true);
                }

                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        //结束装箱
        public int Dispatch(bool isFilled)
        {
            int result = -1;
            errorstring = "Dispatch error!";
            try
            {
                string dispatchStationNr = myConfig.DipatchValidationSetting.user;
                ItacMES.shipActivateShippingLotAtKap(sessionId, dispatchStationNr, dispatchMaterialBinNr, out errorstring);
                if (quantity == totalQuantity)
                {
                    result = ItacMES.shipCompleteLot(sessionId, dispatchStationNr, dispatchMaterialBinNr, 0, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) return result;
                }
                else
                {
                    result = ItacMES.shipCompleteLot(sessionId, dispatchStationNr, dispatchMaterialBinNr, 1, out errorstring);
                    if (result != ItacMIIConstants.RES_OK) return result;
                }
                result = ItacMES.shipDeactivateShippingLotAtKap(sessionId, dispatchStationNr, dispatchMaterialBinNr, out errorstring);
                if (result != ItacMIIConstants.RES_OK) return result;
                //update access
                try
                {
                    string sql = string.Format("UPDATE DISPATCH SET QUANTITY = '{0}' WHERE BOXNR = '{1}'", quantity, dispatchMaterialBinNr);
                    AccessHelper.excuteSql(sql);
                }
                catch (System.Exception ex)
                {
                    return -1006;
                }
                //todo
                //打印箱号
                string date = DateTime.Now.ToString("yyyyMMdd");
                if (!PrintExcel(dispatchMaterialBinNr, quantity, date))
                    return -1;
                //装箱后清除箱号
                dispatchMaterialBinNr = string.Empty;
                quantity = 0;
                return result;
            }
            catch (System.Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }

        //第8站做的FunctionTest
        public int FunctionTest(string serialNumber)
        {
            return ItacMES.uploadState(this.sessionId, "R06112010", 2, serialNumber, "-1", 0, 0, 0, out errorstring);
        }

        public bool PrintExcel(string dispatchMaterialBinNr, int quantity, string date)
        {
            ShippingLotStruct shippingLot;
            int result = ItacMES.shipGetShippingLotForLotNo(sessionId, myConfig.DipatchValidationSetting.user, dispatchMaterialBinNr, out shippingLot, out errorstring);
            if (result == ItacMIIConstants.RES_OK)
            {
                quantity = (int)shippingLot.meRest;
                DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
                long tricks_1970 = dt_1970.Ticks;
                DateTime dt = new DateTime(tricks_1970 + Convert.ToInt64(shippingLot.endDate) * 10000000);
                date = dt.ToString("yyyyMMdd");
            }
            Excel.Application xlsApp = null;
            Excel.Workbook workbook = null;
            xlsApp = new Excel.Application();
            xlsApp.Visible = false;
            string file = System.IO.Directory.GetCurrentDirectory();
            file = file + @"\Config\Machine\" + fileName; //todo change
            workbook = xlsApp.Workbooks.Open(file, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            if (workbook == null)
            {
                return false;
            }
            Excel.Worksheet worksheet = workbook.Sheets[1] as Excel.Worksheet;
            Excel.Range range = worksheet.get_Range("C4", Type.Missing);
            range.Value2 = quantity;
            range = worksheet.get_Range("C13", Type.Missing);
            range.Value2 = dispatchMaterialBinNr;
            range = worksheet.get_Range("H11", Type.Missing);
            range.Value2 = date;
            worksheet.PrintOutEx(Type.Missing, Type.Missing, Type.Missing, false, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            workbook.Close(false);
            xlsApp.Quit();
            return true;
        }


        //int cnt = 0;
        public int SetProductState(string serialNumber, string customerSN, int result)//TODO:, the result should be the fail sationNo.
        {
            try
            {
                string stationNr;
                stationNr = myConfig.ValidationSetting.systemIdentifier;
                #region getStationSetup
                int ret = ItacMES.getStationSetup(this.sessionId, stationNr, out this.StationSetup.partNr,
                out this.StationSetup.bomVersion, out this.StationSetup.bomIndex, out this.StationSetup.partDesc,
                out this.StationSetup.workOrder, out this.StationSetup.quantity, out this.StationSetup.state,
                out this.StationSetup.cadPartNr, out this.StationSetup.processLayer, out this.StationSetup.customerName,
                out this.StationSetup.customerPartNr, out this.StationSetup.attribute1, out this.errorstring);
                if (ret != ItacMIIConstants.RES_OK) return ret;
                #endregion
                if (result != 0)
                {
                    //TODO: already find the step in the flow chart page 21
                    #region uploadStateAndFailureData
                    int loopCount = 0;
                    string posDesc = "";
                    int snState = myConfig.UploadStateAndFailureData.SerialNumberState;
                    int duplicateSN = myConfig.UploadStateAndFailureData.DuplicateSerialNumber;
                    string productNo = myConfig.UploadStateAndFailureData.ProductNo;
                    string productVersion = myConfig.UploadStateAndFailureData.ProductRev;
                    string serialNumberPos = myConfig.UploadStateAndFailureData.SerialNumberPos;
                    CompFailData[] failData = new CompFailData[1];
                    failData[0].compName = myConfig.UploadStateAndFailureData.CompName;
                    failData[0].compPartNo = myConfig.UploadStateAndFailureData.CompPartNo;
                    failData[0].processLayer = StationSetup.processLayer;//TODO: Got configuration directly(the old code is got from myConfig.UploadStateAndFailureData.ProcessLayer) or can be from station setup
                    failData[0].failureCause = myConfig.UploadStateAndFailureData.FailureCause;
                    failData[0].infoText = myConfig.UploadStateAndFailureData.InfoText;
                    failData[0].failureType = myConfig.ErrorCodeMapping.GetAttributeCodeAccordingToFailCode(result);
                    failData[0].repair = 0;
                    float cycleTime = 7.0f;
                    int bookDate = -1;
                    ret = ItacMES.uploadStateAndFailureData(this.sessionId, stationNr,
                        StationSetup.processLayer, productNo, productVersion, serialNumber, serialNumberPos, posDesc,
                        snState, duplicateSN, failData, cycleTime, bookDate, out loopCount, out errorstring);
                    if ((ret != ItacMIIConstants.RES_OK)) return ret;
                    #endregion

                    #region appendAttributeToSerialNumber
                    string value = "18" + result.ToString("D2");
                    ItacMES.removeAttributeFromSerialNumber(this.sessionId, stationNr, serialNumber, "RSU_ASS_FAILURE", out errorstring);
                    ret = ItacMES.appendAttributeToSerialNumber(this.sessionId, stationNr,
                        serialNumber, "RSU_ASS_FAILURE", value, out errorstring);
                    #endregion
                }
                else
                {
                    int loopcounter = 0;
                    ret = ItacMES.checkSerialNumberState(this.sessionId, stationNr, 2, serialNumber, "-1", out loopcounter, out errorstring);
                    if (ret != 0)
                    {
                        //return -1;
                    }
                    #region getSerialNumbersForAttribute
                    SerialNumberStruct[] serialNumberArray = null;

                    //ret = ItacMES.getSerialNumbersForAttribute(this.sessionId, stationNr,
                    //    myConfig.GetSerialNumbersForAttribute.AttributeCode, customerSN, out serialNumberArray, out errorstring);
                    //if (ret != ItacMIIConstants.RES_OK)
                    //    throw new Exception(ret.ToString() + " " + this.errorstring + " getSerialNumbersForAttribute 错误，请联系ITAC工程师");
                    //string sn=serialNumberArray[0].serialNumber;
                    #endregion
                    //Added for packing.

                    #region uploadState
                    string snRefPos = "-1";//myConfig.UploadState.SerialNumberRefPos;
                    int snState = 0;//TODO:, need to be check.
                    int duplicateSN = myConfig.UploadState.DuplicateSerialNumber;
                    int checkActiveWO = myConfig.UploadState.CheckActiveWorkOrder;

                    ret = ItacMES.uploadState(this.sessionId, stationNr, StationSetup.processLayer,
                        serialNumber, snRefPos, snState, duplicateSN, checkActiveWO, out errorstring);
                    if ((ret != ItacMIIConstants.RES_OK)) return ret;
                    #endregion

                    #region appendAttributeToSerialNumber
                    ret = ItacMES.appendAttributeToSerialNumber(this.sessionId, stationNr,
                        serialNumber, myConfig.AppendAttributeToSerialNumber.AttributeCode_Pass, customerSN, out errorstring);
                    #endregion
                }


                //TODO:, the follow code is repeat step,need check why use this repeat step in old code
                if (ret != 0)
                {
                    if (result != 0)
                    {
                        #region uploadStateAndFailureData
                        int loopCount = 0;
                        string posDesc = "";
                        int snState = myConfig.UploadStateAndFailureData.SerialNumberState;
                        int duplicateSN = myConfig.UploadStateAndFailureData.DuplicateSerialNumber;
                        string productNo = myConfig.UploadStateAndFailureData.ProductNo;
                        string productVersion = myConfig.UploadStateAndFailureData.ProductRev;
                        string serialNumberPos = myConfig.UploadStateAndFailureData.SerialNumberPos;
                        CompFailData[] failData = new CompFailData[1];
                        failData[0].compName = myConfig.UploadStateAndFailureData.CompName;
                        failData[0].compPartNo = myConfig.UploadStateAndFailureData.CompPartNo;
                        failData[0].processLayer = StationSetup.processLayer;//TODO: Got configuration directly(the old code is got from myConfig.UploadStateAndFailureData.ProcessLayer) or can be from station setup
                        failData[0].failureCause = myConfig.UploadStateAndFailureData.FailureCause;
                        failData[0].infoText = myConfig.UploadStateAndFailureData.InfoText;
                        failData[0].failureType = myConfig.ErrorCodeMapping.GetAttributeCodeAccordingToFailCode(result);//TODO: need to be check
                        failData[0].repair = 0;
                        float cycleTime = 7.0f;
                        int bookDate = -1;
                        ret = ItacMES.uploadStateAndFailureData(this.sessionId, stationNr,
                            StationSetup.processLayer, productNo, productVersion, serialNumber, serialNumberPos, posDesc,
                            snState, duplicateSN, failData, cycleTime, bookDate, out loopCount, out errorstring);
                        if ((ret != ItacMIIConstants.RES_OK)) return ret;
                        #endregion
                    }
                    #region appendAttributeToSerialNumber
                    ret = ItacMES.appendAttributeToSerialNumber(this.sessionId, stationNr,
                        serialNumber, myConfig.AppendAttributeToSerialNumber.AttributeCode_Pass, customerSN, out errorstring);
                    #endregion
                }
                //repeat code end
                return ret;
            }
            catch (Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return -1;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="customerSN"></param>
        /// <param name="lotNo"></param>
        /// <param name="packStatus">=0 means successful,=1 means full, =-1 means failed</param>
        /// <returns></returns>
        public int Packing(string customerSN, string lotNo, out int packStatus)
        {
            try
            {
                packStatus = -1;
                #region getStationSetup
                int ret = ItacMES.getStationSetup(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier, out this.StationSetup.partNr,
                out this.StationSetup.bomVersion, out this.StationSetup.bomIndex, out this.StationSetup.partDesc,
                out this.StationSetup.workOrder, out this.StationSetup.quantity, out this.StationSetup.state,
                out this.StationSetup.cadPartNr, out this.StationSetup.processLayer, out this.StationSetup.customerName,
                out this.StationSetup.customerPartNr, out this.StationSetup.attribute1, out this.errorstring);
                if (ret != ItacMIIConstants.RES_OK) return ret;
                #endregion

                #region getSerialNumbersForAttribute
                SerialNumberStruct[] serialNumberArray = null;
                ret = ItacMES.getSerialNumbersForAttribute(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier,
                    myConfig.GetSerialNumbersForAttribute.AttributeCode, customerSN, out serialNumberArray, out errorstring);
                if (ret != ItacMIIConstants.RES_OK) return ret;
                string snFromGetSerialNumberForAttribute = serialNumberArray[0].serialNumber;
                #endregion

                #region verifyMerge
                ret = ItacMES.verifyMerge(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier, snFromGetSerialNumberForAttribute, out errorstring);
                if (ret != ItacMIIConstants.RES_OK) return ret;
                #endregion

                #region assignSerialNumberMergeAndUploadState
                SerialNumberData[] snData = new SerialNumberData[1];
                snData[0].serialNumber = snFromGetSerialNumberForAttribute;
                snData[0].serialNumberPos = "-1";
                ret = ItacMES.assignSerialNumberMergeAndUploadState(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier, StationSetup.processLayer,
                    snFromGetSerialNumberForAttribute, "1", 1, snData, snFromGetSerialNumberForAttribute, 1, 0, out errorstring);
                if (ret != ItacMIIConstants.RES_OK) return ret;
                #endregion

                #region switchSerialNumber
                ret = ItacMES.switchSerialNumber(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier, StationSetup.processLayer, 0,
                    snFromGetSerialNumberForAttribute, customerSN, out errorstring);
                if (ret != ItacMIIConstants.RES_OK) return ret;
                #endregion

                #region shipAddSnrToShippingLot
                ret = ItacMES.shipAddSnrToShippingLot(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier, lotNo, customerSN, out errorstring);
                if ((ret != 0) && (ret != 1) && (ret != 2))
                {
                    return ret;
                }
                #endregion

                #region shipGetShippingLotForLotNo
                ShippingLotStruct shippingLot = new ShippingLotStruct();
                ret = ItacMES.shipGetShippingLotForLotNo(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier, lotNo, out shippingLot, out errorstring);
                if (ret != ItacMIIConstants.RES_OK) return ret;
                if (shippingLot.meTotal == shippingLot.meRest)
                {
                    packStatus = 1;
                    ret = ItacMES.shipCompleteLot(this.sessionId, myConfig.DipatchValidationSetting.systemIdentifier, lotNo, 0, out errorstring);
                    if (ret != ItacMIIConstants.RES_OK) return ret;
                }
                else
                {
                    packStatus = 0;
                }
                #endregion
                return 0;
            }
            catch (Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            packStatus = -1;
            return -1;
        }

        public bool GetSerialnumberInfo(string txSN)
        {
            try
            {
                #region getSerialnumberInfo
                int ret = ItacMES.getSerialnumberInfo(this.sessionId, txSN, "-1", out this.SNInfo.partNr,
                out this.SNInfo.bomVersion, out this.SNInfo.bomIndex, out this.SNInfo.partDesc,
                out this.SNInfo.workOrder, out this.SNInfo.quantity, out this.SNInfo.state,
                out this.SNInfo.cadPartNr, out this.SNInfo.customerName,
                out this.SNInfo.customerPartNr, out this.SNInfo.attribute1, out this.errorstring);
                if (ret != ItacMIIConstants.RES_OK) return false;
                #endregion
                return true;
            }
            catch (Exception ex)
            {
                SimpleLog(ex.Message);
                ExManager.HandleException(ex, "Policy");
            }
            return false;
        }

        public int GetIdStatesReinjection(string pr_id)
        {
            //int ret = trac.GetIdStatesReinjection(szStation, pr_id);
            return 0;
        }

        public string CreateCustomerSN(int sessionId, string producttype, string serialNumber,
            string contextFormat, string format, int length, string dataFormat,
            ref string customersncontext, ref string dddy)
        {
            int ret = 0;
            string formatstr = contextFormat;
            string ICID = string.Empty;
            string dailynum = string.Empty;
            string customerId = "Error";
            string stationNr;
            stationNr = myConfig.ValidationSetting.systemIdentifier;

            //第8站做的TEST
            //ItacMES.uploadState(this.sessionId, "R06112010", 2, serialNumber, "-1", 0, 0, 0, out errorstring);
            //
            //
            //

            if ((formatstr.Contains("IC")) || (formatstr.Contains("DN")))
            {
                #region getStationSetup

                ret = ItacMES.getStationSetup(this.sessionId, myConfig.ValidationSetting.systemIdentifier, out this.StationSetup.partNr,
                out this.StationSetup.bomVersion, out this.StationSetup.bomIndex, out this.StationSetup.partDesc,
                out this.StationSetup.workOrder, out this.StationSetup.quantity, out this.StationSetup.state,
                out this.StationSetup.cadPartNr, out this.StationSetup.processLayer, out this.StationSetup.customerName,
                out this.StationSetup.customerPartNr, out this.StationSetup.attribute1, out this.errorstring);
                if (ret != ItacMIIConstants.RES_OK) return customerId;
                #endregion
                if (formatstr.Contains("IC"))        //get ICID
                {
                    #region getAttributesForSerialNumber
                    SnrAttributeInfo[] snrAttributeInformation = null;
                    ret = ItacMES.getAttributesForSerialNumber(sessionId, stationNr,
                        serialNumber, myConfig.AttributeCodeForContext, out snrAttributeInformation, out errorstring);
                    if (ret != ItacMIIConstants.RES_OK) return customerId;
                    ICID = snrAttributeInformation[0].attributeValue;
                    #endregion
                }
                if (formatstr.Contains("DN")) //get daily number     
                {
                    #region getNextSerialNumberForWorkOrder
                    int serialNumberArraySize = 1;
                    SerialNumberData[] snData = null;
                    ret = ItacMES.getNextSerialNumberForWorkOrder(sessionId, stationNr,
                        StationSetup.workOrder, ref serialNumberArraySize, out snData, out errorstring);
                    if (ret != ItacMIIConstants.RES_OK) return customerId;
                    dailynum = snData[0].serialNumber;
                    #endregion
                }
            }
            dddy = MakeDateContext(producttype, dataFormat);
            customersncontext = MakeCustomerSnContext(producttype, serialNumber, contextFormat, dailynum, ICID);
            customerId = MakeCustomerSn(producttype, serialNumber, format, customersncontext, dailynum, ICID);
            CheckCustomerSn(ref customerId, ref customersncontext, ref dddy);
            return customerId;
        }

        private string MakeCustomerSnContext(string producttype, string serialNumber, string contextFormat, string dailyNumber, string ICID)  //1D barcode
        {

            string formatstr = "";
            formatstr = contextFormat;

            string cussn_context = "";

            string exp = "";
            int mth = DateTime.Now.Month;
            string monthStr = "";
            string year = "";
            int index = 0;
            int pos = 0;
            string[] items;
            string serialno = "";
            string exp1 = "";

            items = formatstr.Split('/');
            foreach (string item in items)
            {
                if (item.Contains("{"))          /******          Special Part with "{  }"       ************/
                {
                    exp = "";
                    exp = item;
                    index = item.IndexOf(":") + 1;


                    if (item.StartsWith("DN"))  /**********   DN Part       ************/
                    {
                        exp = exp.TrimEnd('}');
                        pos = int.Parse(exp.Substring(index));
                        int dailynum = int.Parse(dailyNumber);

                        // daily num
                        if (item.Contains("n"))     //decimal 
                        {
                            exp = string.Concat("{0:D", pos, '}');
                            exp1 = string.Format(exp, dailynum);
                            //     cussn_context += string.Format(exp, dailynum);

                        }

                        if (item.Contains("h"))        // heximal
                        {

                            exp = string.Concat("{0:X", pos, '}');
                            exp1 = string.Format(exp, dailynum);

                        }

                        cussn_context += exp1.Substring(exp1.Length - pos);

                    }

                    else if (item.StartsWith("SN"))    /******          SN Part       ************/
                    {
                        exp = exp.TrimEnd('}');
                        pos = int.Parse(exp.Substring(index));

                        if (item.Contains("n"))     //decimal 
                        {
                            serialno = serialNumber;
                            if (serialno.Length > 9)
                            {
                                cussn_context += serialno.Substring(serialno.Length - pos);
                            }
                            else
                            {
                                //Logging.WriteInfo("Create customer sn: Invalid serialnumber:" + serialno);
                                return "Error";
                            }
                        }
                    }
                    else
                    {
                        //deal with user defined part
                        // exp = item;
                        exp = exp.TrimStart('{');
                        exp = exp.TrimEnd('}');
                        cussn_context += exp;
                    }

                }
                else           /******         Normal Case Part       ************/
                {
                    switch (item)
                    {
                        case "YYYY":
                            year = Convert.ToString(DateTime.Now.Year);
                            cussn_context = cussn_context + year.ToString();
                            break;

                        case "YY":
                            year = Convert.ToString(DateTime.Now.Year);
                            cussn_context += year.Substring(2);
                            break;

                        case "Y":
                            year = Convert.ToString(DateTime.Now.Year);
                            cussn_context += year.Substring(3);
                            break;

                        case "DDD":
                            cussn_context += string.Format("{0:D3}", DateTime.Now.DayOfYear);
                            break;

                        case "SP":
                            //cussn_context = this.inireader.IniReadValue(producttype, "SP");
                            break;

                        case "IC":
                            string icid = ICID;
                            cussn_context += icid;
                            break;

                        case "M":
                            if (mth == 10) monthStr = "X";
                            else if (mth == 11) monthStr = "Y";
                            else if (mth == 12) monthStr = "Z";
                            else monthStr = Convert.ToString(mth);

                            cussn_context += monthStr;
                            break;

                        case "MM":
                            cussn_context += string.Format("{0:D2}", mth);
                            break;

                        case "DD":
                            cussn_context += string.Format("{0:D2}", DateTime.Now.Day);
                            break;

                        case "WK":
                            cussn_context += string.Format("{0:D2}", CalculateWeekOfYear());
                            break;

                        default:
                            cussn_context += "";
                            break;
                    }
                }
            }
            //Logging.WriteInfo(string.Format("{0}-{1}", "CustomerSerialNumberContext", cussn_context));
            return cussn_context;
        }
        private string MakeCustomerSn(string producttype, string serialNumber, string format, string customerSNContext, string dailyNumber, string ICID) //2D barcode
        {
            string formatstr = "";
            formatstr = format;

            string[] items;
            items = formatstr.Split('/');

            string cus_sn = "";

            int mth = DateTime.Now.Month;
            string monthStr = "";
            string year = "";
            string serialno = "";
            int pos = 0;
            string exp = "";
            string exp1 = "";
            int index = 0;
            foreach (string item in items)
            {
                if (item.Contains("{"))          /******          Special Part with "{  }"       ************/
                {
                    exp = "";
                    exp = item;
                    index = item.IndexOf(":") + 1;

                    if (item.StartsWith("CN"))  /**********   CN Part       ************/
                    {
                        exp = exp.TrimEnd('}');
                        pos = int.Parse(exp.Substring(index));
                        string cus_context = customerSNContext;
                        if (cus_context.Length < pos)
                        {
                            return "Error";
                        }
                        if (item.Contains("f")) exp = cus_context.Substring(0, pos);  //deal from the front
                        if (item.Contains("b")) exp = cus_context.Substring(cus_context.Length - pos);    // deal fron the back

                        cus_sn += exp;
                    }

                    else if (item.StartsWith("SN"))    /******          SN Part       ************/
                    {
                        exp = exp.TrimEnd('}');
                        pos = int.Parse(exp.Substring(index));

                        if (item.Contains("n"))     //decimal 
                        {

                            serialno = serialNumber;

                            if (serialno.Length > 9)
                            {
                                cus_sn += serialno.Substring(serialno.Length - pos);
                            }
                            else
                            {
                                return "Error";
                            }

                        }
                    }
                    else if (item.StartsWith("DN"))  /**********   DN Part       ************/
                    {
                        exp = exp.TrimEnd('}');
                        pos = int.Parse(exp.Substring(index));
                        int dailynum = int.Parse(dailyNumber);

                        // daily num
                        if (item.Contains("n"))     //decimal 
                        {
                            exp = string.Concat("{0:D", pos, '}');
                            exp1 = string.Format(exp, dailynum);
                            //     cussn_context += string.Format(exp, dailynum);

                        }

                        if (item.Contains("h"))        // heximal
                        {

                            exp = string.Concat("{0:X", pos, '}');
                            exp1 = string.Format(exp, dailynum);

                        }

                        cus_sn += exp1.Substring(exp1.Length - pos);

                    }
                    else
                    {
                        //deal with user defined part
                        // exp = item;
                        exp = exp.TrimStart('{');
                        exp = exp.TrimEnd('}');
                        cus_sn += exp;
                    }

                }
                else           /******         Normal Case Part       ************/
                {
                    switch (item)
                    {
                        case "YYYY":
                            cus_sn = string.Concat(cus_sn, DateTime.Now.Year);
                            break;

                        case "YY":
                            year = Convert.ToString(DateTime.Now.Year);
                            cus_sn += year.Substring(2);
                            break;

                        case "Y":
                            year = Convert.ToString(DateTime.Now.Year);
                            cus_sn += year.Substring(3);
                            break;

                        case "DDD":
                            cus_sn += string.Format("{0:D3}", DateTime.Now.DayOfYear);
                            break;


                        case "SP":
                            //cus_sn += Convert.ToString(inireader.IniReadValue(producttype, "SP"));
                            //TODO:
                            break;

                        case "IC":
                            string icid = ICID;
                            cus_sn += icid;
                            break;

                        case "M":

                            if (mth == 10)
                            {
                                monthStr = "X";
                            }
                            else if (mth == 11)
                            {
                                monthStr = "Y";
                            }
                            else if (mth == 12)
                            {
                                monthStr = "Z";

                            }
                            else
                            {
                                monthStr = Convert.ToString(mth);
                            }

                            cus_sn += monthStr;
                            //   cus_sn = string.Concat(cus_sn, monthStr);
                            break;

                        case "MM":
                            cus_sn += string.Format("{0:D2}", mth);
                            break;

                        case "DD":
                            cus_sn += string.Format("{0:D2}", DateTime.Now.Day);
                            break;

                        case "WK":
                            cus_sn += string.Format("{0:D2}", CalculateWeekOfYear());
                            break;

                        default:
                            cus_sn += "";
                            break;
                    }
                }
            }
            //Logging.WriteInfo(string.Format("{0}-{1}", "CustomerSerialNumber", cus_sn));

            return cus_sn;
        }
        private string MakeDateContext(string producttype, string dataFormat)
        {
            string formatstr = "";
            formatstr = dataFormat;

            if (formatstr.Trim() == "") return "";

            int mth = DateTime.Now.Month;
            string monthStr = "";
            string year = "";
            string[] items;
            string datestr = "";
            items = formatstr.Split('/');

            foreach (string item in items)
            {
                switch (item)
                {
                    case "YYYY":
                        year = Convert.ToString(DateTime.Now.Year);
                        datestr = datestr + year.ToString();
                        break;

                    case "YY":
                        year = Convert.ToString(DateTime.Now.Year);
                        datestr += year.Substring(2);
                        break;

                    case "Y":
                        year = Convert.ToString(DateTime.Now.Year);
                        datestr += year.Substring(3);
                        break;

                    case "DDD":
                        datestr += string.Format("{0:D3}", DateTime.Now.DayOfYear);
                        break;

                    case "M":
                        if (mth == 10) monthStr = "X";
                        else if (mth == 11) monthStr = "Y";
                        else if (mth == 12) monthStr = "Z";
                        else monthStr = Convert.ToString(mth);

                        datestr += monthStr;
                        break;

                    case "MM":
                        datestr += string.Format("{0:D2}", mth);
                        break;

                    case "DD":
                        datestr += string.Format("{0:D2}", DateTime.Now.Day);
                        break;

                    case "WK":
                        datestr += string.Format("{0:D2}", CalculateWeekOfYear());
                        break;

                    default:
                        datestr += "";
                        break;

                }
            }
            return datestr;
        }
        private void CheckCustomerSn(ref string customersn, ref string customersncontext, ref string dddy)
        {
            if ((customersn == "") || (customersncontext == "") || (dddy == ""))
            {
                customersn = "Error";
                customersncontext = "Error";
                dddy = string.Format("{0:D3}", DateTime.Now.DayOfYear);
                //MessageBox.Show("Customer serialnumber error! // 客户序列号生成错误", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
            }

        }

        private int CalculateWeekOfYear()
        {
            CultureInfo ci = CultureInfo.CurrentCulture;
            Calendar cd = ci.Calendar;
            int wk = cd.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
            return wk;
        }
        private void SimpleLog(string message)
        {
            LogEntry e = new LogEntry(message, "SimpleLog", 0, 0, System.Diagnostics.TraceEventType.Information, "", null);
            Logger.Write(e);
        }

        [DllImport("Kernel32.dll")]
        private extern static IntPtr LoadLibrary(String path);
        [DllImport("Kernel32.dll")]
        private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);
        [DllImport("Kernel32.dll")]
        private extern static bool FreeLibrary(IntPtr lib);

        delegate int OpenCANCard(int port);
        delegate int CloseCANCard();
        delegate int GetECU_SN(string szSN, int iSize, string errMsg);
        OpenCANCard openCANCard;
        CloseCANCard closeCANCard;
        GetECU_SN getECU_SN;
        private IntPtr hLib;
        public int LoadCanDll(string dllName)
        {
            hLib = LoadLibrary(dllName);
            IntPtr apiFunc = GetProcAddress(hLib, "OpenCANCard");
            if (apiFunc.ToInt32() == 0)
                return -1;
            openCANCard = (Delegate)Marshal.GetDelegateForFunctionPointer(apiFunc, typeof(OpenCANCard)) as OpenCANCard;
            apiFunc = GetProcAddress(hLib, "CloseCANCard");
            if (apiFunc.ToInt32() == 0)
                return -1;
            closeCANCard = (Delegate)Marshal.GetDelegateForFunctionPointer(apiFunc, typeof(CloseCANCard)) as CloseCANCard;
            apiFunc = GetProcAddress(hLib, "GetECU_SN");
            if (apiFunc.ToInt32() == 0)
                return -1;
            getECU_SN = (Delegate)Marshal.GetDelegateForFunctionPointer(apiFunc, typeof(GetECU_SN)) as GetECU_SN;
            return 0;
        }

        public int FreeCanDll()
        {
            if (FreeLibrary(hLib))
                return 0;
            else
                return -1;
        }

        public int GetEcuSN(out string sn, out int size, out string errMsg)
        {
            sn = string.Empty;
            errMsg = string.Empty;
            size = 0;
            if (openCANCard(0) == -1)
                return -1;
            Thread.Sleep(500);
            if (-1 == getECU_SN(sn, size, errMsg))
                return -2;
            if (closeCANCard() == -1)
                return -3;
            return 0;
        }

        private void ItacLog(string msg)
        {
            msg += DateTime.Now.ToString();
            Logger.Write(msg, "ITAC", 0, 0, System.Diagnostics.TraceEventType.Information, "", null);
        }

        public void ClearMaterialTable()
        {
            currentMaterialTable.Rows.Clear();
            currentMaterialTable.Columns.Clear();

            activeMaterialTable.Rows.Clear();
            activeMaterialTable.Columns.Clear();

            st1MaterialTable.Rows.Clear();
            st1MaterialTable.Columns.Clear();
        }
    }

    public delegate void TracConnectedHandler(object sender, int e);
    public delegate void TracConnectClosedHandler(object sender, int e);

}